<?php
namespace Mxfuns;

use Exception;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
/**
 * 调用方式 \Mxfuns\hello()
 * @return string
 */
function hello() {
    return 'Hey, man~';
}

/**
 * 转化文件大小单位
 * @param $size
 * @return string
 */
function formatBytes($size) {
    $units = array(' B', ' KB', ' MB', ' GB', ' TB');
    for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024;
    return round($size, 2).$units[$i];
}

/**
 * @param string $tokenExpire 令牌过期时间
 * @param string $days 令牌有效期
 * @return bool
 */
function tokenExpired($tokenExpire, $days){
    $begin_date = strtotime($tokenExpire);
    $end_date = date('Y-m-d H:i:s',strtotime('+1week'));
    if(round(($end_date - $begin_date) / 3600 / 24)<$days){
        return false;
        }
    return true;
}

/**
 * 生成唯一订单号
 * @return string
 */
function ordersn2(){
    $yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
    $orderSn = $yCode[intval(date('Y')) - 2015].date("YmdHis",time()).sprintf('%03d%02d', rand(100, 999),rand(0,99));
    return $orderSn;
}

/**
 * 生产唯一订单号
 * @return string
 */
function ordersn3(){
    $yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
    $orderSn = $yCode[intval(date('Y')) - 2015] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%04d%02d', rand(1000, 9999),rand(0,99));
    return $orderSn;
}

/**
 * 匹配中文
 * @param  [type] $string [description]
 * @return int [type]         [description]
 */
function check_chinese($string){
    $pattern = "/^[\x{4e00}-\x{9fa5}]+$/u";
    return preg_match($pattern, $string);
}


//检查身份证号
function check_idcard($idcard){

    // 只能是18位
    if(strlen($idcard)!=18){
        return false;
    }

    // 取出本体码
    $idcard_base = substr($idcard, 0, 17);

    // 取出校验码
    $verify_code = substr($idcard, 17, 1);

    // 加权因子
    $factor = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);

    // 校验码对应值
    $verify_code_list = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');

    // 根据前17位计算校验码
    $total = 0;
    for($i=0; $i<17; $i++){
        $total += substr($idcard_base, $i, 1)*$factor[$i];
    }

    // 取模
    $mod = $total % 11;

    // 比较校验码
    if($verify_code == $verify_code_list[$mod]){
        return true;
    }else{
        return false;
    }
}



/**
 * 检查手机号格式是否正确
 *
 * @param  string $str 手机号
 * @return bool
 */
function check_mobile($str) {
    $reg = "/13[0-9]{1}\d{8}|14[5,7]\d{8}|15[012356789]\d{8}|18[012356789]\d{8}/";
    $pattern = "/^((1[3,5,8][0-9])|(14[5,7])|(17[0,6,7,8]))\d{8}$/";
    return preg_match($reg, $str);
}


/**
 * 检查邮件地址格式是否正确
 *
 * @param  string $str 邮件地址
 * @return bool
 */
function check_mail($str){
    //return preg_match('/^[^0-9][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[@][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[.][a-zA-Z]{2,4}$/',$mail);
    return filter_var($str, FILTER_VALIDATE_EMAIL);
}


/**
 * 检查是否是邮编
 *
 * @param $postcode
 * @return bool
 * @internal param string $code 邮编
 */
function check_post($postcode) {
    $reg = "/^[0-9]d{5}$/";
    return preg_match($reg, $postcode);
}


/**
 * 检查是否是国内电话号格式
 * @param  string $tel 电话号码
 * @return bool
 */
function  check_telphone($tel) {
    $isTel="/^([0-9]{3,4}-)?[0-9]{7,8}$/";
    preg_match($isTel, $tel);
}


//检查用户名
function check_username ($username) {
    return preg_match('/^[a-z\d_]{5,20}$/i', $username);
}


//检查IPV4
function check_ipv4($ip) {
    return preg_match('/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/',$ip);
}


//检查url
function check_url($url) {
    return preg_match('/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i', $url);
}
/**
 * 获取汉字字符串的首字母
 * @param  [type] $str [description]
 * @return [type]      [description]
 */
function getfirstchar($str) {
    $fchar = $str[0];
    //判断是否为字符串
    if (ord($fchar) >= ord("A") && ord($fchar) <= ord("z")) {
        return strtoupper($fchar);
    }

    $str = iconv("UTF-8", "gb2312", $str);
    $asc = ord($str[0]) * 256 + ord($str[1]) - 65536;
    if ($asc >= -20319 and $asc <= -20284) return "A";
    if ($asc >= -20283 and $asc <= -19776) return "B";
    if ($asc >= -19775 and $asc <= -19219) return "C";
    if ($asc >= -19218 and $asc <= -18711) return "D";
    if ($asc >= -18710 and $asc <= -18527) return "E";
    if ($asc >= -18526 and $asc <= -18240) return "F";
    if ($asc >= -18239 and $asc <= -17923) return "G";
    if ($asc >= -17922 and $asc <= -17418) return "H";
    if ($asc >= -17417 and $asc <= -16475) return "I";
    if ($asc >= -16474 and $asc <= -16213) return "J";
    if ($asc >= -16212 and $asc <= -15641) return "K";
    if ($asc >= -15640 and $asc <= -15166) return "L";
    if ($asc >= -15165 and $asc <= -14923) return "M";
    if ($asc >= -14922 and $asc <= -14915) return "N";
    if ($asc >= -14914 and $asc <= -14631) return "P";
    if ($asc >= -14630 and $asc <= -14150) return "Q";
    if ($asc >= -14149 and $asc <= -14091) return "R";
    if ($asc >= -14090 and $asc <= -13319) return "S";
    if ($asc >= -13318 and $asc <= -12839) return "T";
    if ($asc >= -12838 and $asc <= -12557) return "W";
    if ($asc >= -12556 and $asc <= -11848) return "X";
    if ($asc >= -11847 and $asc <= -11056) return "Y";
    if ($asc >= -11055 and $asc <= -10247) return "Z";
    return null;
}


/**
 * csv文件导入
 *
 * @param  [type] $filedname 上传文件字段名
 * @return array  将上传csv文件内容转为数组
 */
function import_csv($filedname){
    $filename = $_FILES[$filedname]['tmp_name'];
    if(empty($filename)){
        echo "请选择要导入的CSV文件";exit;
    }

    $handle = fopen($filename, 'r');
    $csv_fileconent = array();

    $n = 0;
    while ($rows = fgetcsv($handle, 10000)){
        $num = count($rows);
        for ($i = 0; $i < $num; $i++){
            $csv_fileconent[$n][$i] = $rows[$i];
        }
        $n++;
    }

    fclose($handle);

    return $csv_fileconent;
}


/**
 * 将数据导出为csv文件
 * @param $filename
 * @param $header
 * @param $data
 * @internal param $ [type] $filename [description]
 * @internal param $ [type] $data     [description]
 * @internal param $ [type] $header    [<description>]
 */
function export_csv($filename, $header, $data){
    header("Content-type:text/csv; charset=utf-8");
    header("Content-Disposition:attachment;filename=".date('YmdHis')."_".$filename);
    header('Cache-Control:must-revalidate,post-check=0,pre-check=0');
    header('Expires:0');
    header('Pragma:public');

    ob_start();

    $csv_data = "";
    if($header){
        $csv_data .= implode(",", $header)."\n";
    }

    if($data){
        foreach($data as $item){
            $csv_data .= implode(",", $item)."\n";
        }
    }

    ob_end_clean();

    echo $csv_data;
}

/**
     *创建并写入文件
     * @param string $path 文件路径
     * @param null $data 写入数据默认为空
     * @param null $name 文件名默认为随机字符串
     * @param string $mode 追加还是覆盖默认为覆盖
     * @throws Exception
     */
    function createFile($path,$data = NULL,$name = NULL ,$mode = 'w') {


        $dir  = explode('/', $path);
        $path = '';
        foreach ($dir as $element) {
            $path .= $element . '/';
            if (!is_dir($path) && !mkdir($path)) {
                throw new Exception(
                    'create file path Error:' . $path
                );
            }
        }
        if(!$name){
            $name = 'tmp'.createRandStr(9);
        }
        try{
            $mode = $mode =='w' ? 'w' : 'a';
            $file = fopen($path.$name, $mode);
            fwrite($file, $data);
            fclose($file);
        }catch ( Exception $e){
            echo $e->getMessage();
             die(); // 终止异常
        }

    }

    /**
     * 使用 spl 库
     *
     * @param $path
     * @return array
     */
    function getDir5($path)
    {
        $dir = new RecursiveDirectoryIterator($path);
        $fileItem = [];
        foreach(new RecursiveIteratorIterator($dir) as $k=>$v) {

            $fileName = $v->getBaseName();
            if($fileName != '.' && $fileName != '..') {
                $fileItem[] = $k;
            }
        }

        return $fileItem;
    }
	
/**
 * 格式化 12312432.23 to ￥12,312,432.23
 * @N_money string
 * @param none $N_money
 * @return string
 */
function ExchangeMoney($N_money) {
    $A_tmp=explode(".",$N_money ); //将数字按小数点分成两部分，并存入数组$A_tmp
    $I_len=strlen($A_tmp[0]); //测出小数点前面位数的宽度
    $I_step = 0;

    if($I_len%3==0) {
        $I_step=$I_len/3; //如前面位数的宽度mod 3 = 0 ,可按，分成$I_step 部分
    }
    else {
        $I_step=($I_len-$I_len%3)/3+1; //如前面位数的宽度mod 3 != 0 ,可按，分成$I_step 部分+1
    }

    $C_cur="";

    //对小数点以前的金额数字进行转换
    while($I_len<>0){
        $I_step--;

        if ($I_step==0) {
            $C_cur .= substr($A_tmp[0],0,$I_len-($I_step)*3);
        }
        else {
            $C_cur .= substr($A_tmp[0],0,$I_len-($I_step)*3).",";
        }

        $A_tmp[0]=substr($A_tmp[0],$I_len-($I_step)*3);
        $I_len=strlen($A_tmp[0]);
    }

    //对小数点后面的金额的进行转换
    if ($A_tmp[1]=="") {
        $C_cur .= ".00";
    }
    else {
        $I_len=strlen($A_tmp[1]);

        if ($I_len<2) {
            $C_cur .= ".".$A_tmp[1]."0";
        }
        else {
            $C_cur .= ".".substr($A_tmp[1],0,2);
        }
    }

    //加上人民币符号并传出
    $C_cur="￥".$C_cur;
    return $C_cur;
}


/**
 * Function : dump()
 * Arguments : $data - the variable that must be displayed
 * Prints a array, an object or a scalar variable in an easy to view format.
 */
function dump($data) {
    if(is_array($data)) { //If the given variable is an array, print using the print_r function.
        print "<array-----------------------\n";
        print_r($data);
        print "-----------------------/array>";
    } elseif (is_object($data)) {
        print "<object==========================\n";
        var_dump($data);
        print "===========================/object>";
    } else {
        print "<=========\n";
        var_dump($data);
        print "=========/>";
    }
}


//打印调试，带变量类型
function D($array){
    echo "<pre>";
    var_dump($array);
    echo "</pre>";
}


//打印调试
function P($array){
    echo "<pre>";
    print_r($array);
    echo "</pre>";
}


/**
 * get a file extension name
 * 获取文件扩展名
 *
 * @param  string $filename 文件名称
 * @return string
 */
function getFileExtension($filename) {
    if(empty($filename)) {
        return false;
    }

    $extend = explode(".", $filename);

    return end($extend);
}
/**
     * 随机字符串生成
     *
     * @param int    $len 需要随机的长度，不要太长
     * @param string $chars 随机生成字符串的范围
     *
     * @return string
     */
    function createRandStr($len, $chars = null) {
        if (!$chars) {
            $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        }
        
        return substr(str_shuffle(str_repeat($chars, rand(5, 8))), 0, $len);
    }

    /**
     * 获取数组value值不存在时返回默认值
     * 不建议在大循环中使用会有效率问题
     *
     * @param array      $arr     数组实例
     * @param string|int $key     数据key值
     * @param string     $default 默认值
     *
     * @return string
     */
    function arrIndex($arr, $key, $default = '') {

        return isset($arr[$key]) ? $arr[$key] : $default;
    }

    /**
     * 根据路径创建目录或文件
     *
     * @param string $path 需要创建目录路径
     *
     * @throws PhalApi_Exception_BadRequest
     */
    function createDir($path) {

        $dir  = explode('/', $path);
        $path = '';
        foreach ($dir as $element) {
            $path .= $element . '/';
            if (!is_dir($path) && !mkdir($path)) {
                throw new BadRequestException(
                    T('create file path Error: {filePath}', array('filepath' => $path))
                );
            }
        }
    }

    /**
     * 获取绝对路径，即便不存在的路径也可以转换，而realpath()函数不支持
     * @link https://www.php.net/manual/zh/function.realpath.php
     */
    function getAbsolutePath($path) {
        $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
        $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen');
        $absolutes = array();
        foreach ($parts as $part) {
            if ('.' == $part) continue;
            if ('..' == $part) {
                array_pop($absolutes);
            } else {
                $absolutes[] = $part;
            }
        }
        return implode(DIRECTORY_SEPARATOR, $absolutes);
    }

    /**
     * 删除目录以及子目录等所有文件
     *
     * - 请注意不要删除重要目录！
     *
     * @param string $path 需要删除目录路径
     */
    function deleteDir($path) {

        $dir = opendir($path);
        while (false !== ($file = readdir($dir))) {
            if (($file != '.') && ($file != '..')) {
                $full = $path . '/' . $file;
                if (is_dir($full)) {
                    deleteDir($full);
                } else {
                    unlink($full);
                }
            }
        }
        closedir($dir);
        rmdir($path);
    }

    /**
     * 排除数组中不需要的键
     * @param array $array 待处理的数组，可以是一维数组或二维数组
     * @param string|array $excludeKeys 待排除的键，字符串时使用英文逗号分割
     * @return array 排除key后的新数组
     */
    function arrayExcludeKeys($array, $excludeKeys) {
        if (!is_array($array)) {
            return $array;
        }

        $excludeKeys = is_array($excludeKeys) ? $excludeKeys : explode(',', $excludeKeys);
        foreach ($array as $key => $value) {
            if (is_array($value)) {
                foreach ($array[$key] as $subKey => $subValue) {
                    if (in_array($subKey, $excludeKeys, TRUE)) {
                        unset($array[$key][$subKey]);
                    }
                }
            } else if (in_array($key, $excludeKeys, TRUE)) {
                unset($array[$key]);
            }
        }

        return $array;
    }

    /**
     * 数组转XML格式
     * 
     * @param array $arr 数组
     * @param string $root 根节点名称
     * @param int $num 回调次数
     * 
     * @return string xml
     */
    function arrayToXml($arr, $root='xml', $num=0){
        $xml = '';
        if(!$num){
            $num += 1;
            $xml .= '<?xml version="1.0" encoding="utf-8"?>';
        }
        $xml .= "<$root>";
        foreach ($arr as $key=>$val){
            if(is_array($val) || is_object($val)){
                $xml.=arrayToXml($val,"$key",$num);
            } else {
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml .="</$root>";
        return $xml;
    }
    /**
     * XML格式转数组
     *
     * @param  string $xml
     *
     * @return mixed|array
     */
    function xmlToArray($xml){
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $arr = json_decode(json_encode($xmlstring),true);
        return $arr;
    }
    /**
     * 去除字符串空格和回车
     *
     * @param  string $str 待处理字符串
     *
     * @return string
     */
    function trimSpaceInStr($str)
    {
        $pat = array(" ", "　", "\t", "\n", "\r");
        $string = array("", "", "", "", "", );
        return str_replace($pat, $string, $str);
    }

/**
 * 判断是否是空字符串
 *
 * @param  string $string 字符串
 * @return bool
 */
function isempty($string) {
    if(!is_string($string)) {return false;}
    if (empty($string)) {return false;}
    if($string =="") {return false;}
    return true;
}


/**
 * 中英文混合的字符串截取, 支持utf-8和gb2312
 *
 * @param $string
 * @param $length
 * @param  string $dot [description]
 * @param  string $charset [description]
 * @return string [type]          [description]
 * @internal param $ [type] $string  [description]
 * @internal param $ [type] $length  [description]
 */
function get_word($string, $length, $dot = '..',$charset='utf-8') {

    if(strlen($string) <= $length) {
        return $string;
    }

    $string = str_replace(array('　','&nbsp;', '&', '"', '<', '>'), array('','','&', '"', '<', '>'), $string);

    $strcut = '';
    if(strtolower($charset) == 'utf-8') {

        $n = $tn = $noc = 0;
        while($n < strlen($string)) {

            $t = ord($string[$n]);
            if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
                $tn = 1; $n++; $noc++;
            } elseif(194 <= $t && $t <= 223) {
                $tn = 2; $n += 2; $noc += 2;
            } elseif(224 <= $t && $t < 239) {
                $tn = 3; $n += 3; $noc += 2;
            } elseif(240 <= $t && $t <= 247) {
                $tn = 4; $n += 4; $noc += 2;
            } elseif(248 <= $t && $t <= 251) {
                $tn = 5; $n += 5; $noc += 2;
            } elseif($t == 252 || $t == 253) {
                $tn = 6; $n += 6; $noc += 2;
            } else {
                $n++;
            }

            if($noc >= $length) {
                break;
            }

        }
        if($noc > $length) {
            $n -= $tn;
        }

        $strcut = substr($string, 0, $n);

    } else {
        for($i = 0; $i < $length; $i++) {
            $strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
        }
    }

    return $strcut.$dot;
}


/**
 * 截取中文字符串GB2312
 *
 * @param  string $str 要截取的字符串
 * @param  int $start 开始位置
 * @param  int $len 字符串长度
 * @return string
 */
function cutGBK($str, $start, $len) {
    $tmpstr = "";
    $strlen = $start + $len;
    for ($i=0; $i < $strlen; $i++) {
        if(ord(substr($str, $i, 1) > 0xa0)) {
            $tmpstr .= substr($str, $i, 2);
            $i++;
        }
        else {
            $tmpstr .= substr($str, $i, 1);
        }
    }

    return $tmpstr;
}


/**
 * 截取UTF8字符串
 *
 * @param  string $str 字符串
 * @param  int $start 开始位置
 * @param  int $len 截取的字符串长度
 * @return string
 */
function cutUTF8($str, $start, $len) {
    return preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$start.'}'.'((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$len.'}).*#s','$1',$str);
}


//获取用户的真实IP
function getClientIP() {
    static $realip = NULL;
    if ($realip !== NULL) return $realip;
    if (isset($_SERVER)) {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            foreach ($arr AS $ip) {
                $ip = trim($ip);
                if ($ip != 'unknown') {
                    $realip = $ip;
                    break;
                }
            }
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $realip = $_SERVER['HTTP_CLIENT_IP'];
        } else {
            if (isset($_SERVER['REMOTE_ADDR'])) {
                $realip = $_SERVER['REMOTE_ADDR'];
            } else {
                $realip = '0.0.0.0';
            }
        }
    } else {
        if (getenv('HTTP_X_FORWARDED_FOR')) {
            $realip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('HTTP_CLIENT_IP')) {
            $realip = getenv('HTTP_CLIENT_IP');
        } else {
            $realip = getenv('REMOTE_ADDR');
        }
    }
    preg_match('/[\d\.]{7,15}/', $realip, $onlineip);
    $realip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0';
    return $realip;
}




//检查日期格式是否正确
function check_date($data) {

}

/**
 * 生成随机数字和字母
 *
 * @param  int $len 1-数字 2-小写字母 3-大写字母 4-小写字母和数字
 * @param int $type
 * @return string [type]
 */
function random($len = 6, $type=1) {
    $chars = array(
        1=>"0123456789",
        2=>"abcdefghijklmnopqrstuvwxyz",
        3=>"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
        4=>"abcdefghijklmnopqrstuvwxyz0123456789",
    );
    $salt = "";
    while(strlen($salt) < $len) {
        $salt .= substr($chars[$type], (mt_rand()%strlen($chars[$type])),1);
    }

    return $salt;
}


/**
 * 短信验证码
 * @param  integer $lenght [description]
 * @return string [type]          [description]
 */
function smsNumber($lenght=6){
    $char="1234567890";
    $str = "";
    while(strlen($str) < $lenght){
        $str .= substr($char, (mt_rand()%strlen($char)),1);
    }
    return $str;
}


/**
 * 计算密码强度
 * @param  [type] $string [description]
 * Returns a float between 0 and 100. The closer the number is to 100 the
 * the stronger password is; further from 100 the weaker the password is.
 * @return float|int
 */
function password_strength($string){
    $h    = 0;
    $size = strlen($string);
    foreach(count_chars($string, 1) as $v){
        $p = $v / $size;
        $h -= $p * log($p) / log(2);
    }
    $strength = ($h / 4) * 100;
    if($strength > 100){
        $strength = 100;
    }
    return $strength;
}


/**
 * 隐藏手机号hide mobile like 138****5493
 * @param  [type] $mobile [description]
 * @return [type]         [description]
 */
function hideMobile($mobile)
{
    $pattern = "/(1\d{1,2})\d\d(\d{0,3})/";
    $replacement = "\$1****\$3";
    return preg_replace($pattern, $replacement, $mobile);
}

/**
 * 序列化对象
 * @param $obj
 * @return string
 */
function my_serialize($obj) {
    return base64_encode(gzcompress(serialize($obj)));
}


/**
 * 反序列化为对象
 * @param $txt
 * @return mixed
 */
function my_unserialize($txt) {
    return unserialize(gzuncompress(base64_decode($txt)));
}